﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using Casamiel.API.Application.Models;
using Casamiel.API.Application.Models.ICModels;
using Casamiel.API.Application.Services;
using Casamiel.Application;
using Casamiel.Common;
using Casamiel.Domain.Entity;
using Casamiel.Domain.Request.IC;
using Casamiel.Domain.Response;
using Enyim.Caching;
using MediatR;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Casamiel.API.Application.Commands
{
    /// <summary>
    /// Create member coupon command handler.
    /// </summary>
    public sealed class CreateMemberCouponCommandHandler : IRequestHandler<CreateMemberCouponCommand, BaseResult<string>>
    {
        private readonly IUserLogService _userLogService;
        private readonly IMemcachedClient _memcachedClient;
        private readonly IMemberCouponRecordService _memberCouponRecordService;
        private readonly IIcApiService _icApiService;
        private readonly IMemberCardService _memberCardService;
        private readonly string _memcachedPrex;
        private readonly List<ActivityInfo> _activityInfos;
        /// <summary>
        /// Initializes a new instance of the
        /// <see cref="Casamiel.API.Application.Commands.CreateMemberCouponCommandHandler"/> class.
        /// </summary>
        /// <param name="casamielSettings">Casamiel settings.</param>
        /// <param name="optionsSnapshot">Options snapshot.</param>
        /// <param name="userLogService">User log service.</param>
        /// <param name="memcachedClient">Memcached client.</param>
        /// <param name="memberCardService">Member card service.</param>
        /// <param name="memberCouponRecordService">Member coupon record service.</param>
        /// <param name="icApiService">Ic API service.</param>
        public CreateMemberCouponCommandHandler(IOptionsSnapshot<CasamielSettings> casamielSettings, IOptionsSnapshot<List<ActivityInfo>> optionsSnapshot, IUserLogService userLogService, IMemcachedClient memcachedClient,
                                                IMemberCardService memberCardService, IMemberCouponRecordService memberCouponRecordService, IIcApiService icApiService)
        {
            if (casamielSettings == null) {
                throw new ArgumentNullException(nameof(casamielSettings));
            }

            if (optionsSnapshot == null) {
                throw new ArgumentNullException(nameof(optionsSnapshot));
            }

            _memcachedPrex = casamielSettings.Value.MemcachedPre;
            _userLogService = userLogService;
            _memcachedClient = memcachedClient;
            _icApiService = icApiService;
            _memberCouponRecordService = memberCouponRecordService;
            _activityInfos = optionsSnapshot.Value;
            _memberCardService = memberCardService;
        }


        /// <summary>
        /// Handle the specified request and cancellationToken.
        /// </summary>
        /// <returns>The handle.</returns>
        /// <param name="request">Request.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        public async Task<BaseResult<string>> Handle(CreateMemberCouponCommand request, CancellationToken cancellationToken)
        {
            if (request == null) {
                throw new ArgumentNullException(nameof(request));
            }

            if (request.ActivityId < 1) {
                return new BaseResult<string>("", 999, "活动不存在");
            }

            var activityinfo = _activityInfos.Find(c => c.Id == request.ActivityId);
            if (activityinfo == null) {
                return new BaseResult<string>("", 999, "活动不存在");
            }

            var isCoupon = false;
            if (activityinfo.IsTest && activityinfo.Testers.Contains(new Tester { phoneno = request.Mobile })) {
                isCoupon = true;
            } else {
                if (activityinfo.BeginTime > DateTime.Now) {
                    return new BaseResult<string>("", -31, "尚未开始");
                }
                if (activityinfo.EndTime < DateTime.Now) {
                    return new BaseResult<string>("", -32, "活动结束");
                }
                if (!activityinfo.Enable) {
                    return new BaseResult<string>("", -36, "活动已关闭");
                }
                isCoupon = true;
            }
            if (!isCoupon) {
                return new BaseResult<string>("", -35, "活动不存在");
            }

            var total = 0;//await _memberCouponRecordService.GetCountAync<ICasaMielSession>(request.ActivityId); ;
            var _cachekey = _memcachedPrex + Constant.ACTIVITYTOTAL + request.ActivityId;
            if (activityinfo.Flag == 1) {
                _cachekey = _memcachedPrex + Constant.ACTIVITYTOTAL + request.ActivityId+"_"+DateTime.Now.ToString("yyyyMMdd");
            }
            if (activityinfo.Total > 0) {
                var myda = new Enyim.Caching.Memcached.CasResult<object>();

                if (_memcachedClient.TryGetWithCas(_cachekey, out myda)) {
                    total = (int)myda.Result + 1;
                    _memcachedClient.Cas(Enyim.Caching.Memcached.StoreMode.Replace, _cachekey, total);
                } else {
                    var count = await _memberCouponRecordService.GetCountAsync<ICasaMielSession>(request.ActivityId,activityinfo.Flag).ConfigureAwait(false);
                    total = count + 1;
                    var resultss = _memcachedClient.Cas(Enyim.Caching.Memcached.StoreMode.Add, _cachekey, total);
                }
                if (total > activityinfo.Total) {
                    return new BaseResult<string>("", -34, "券已领完");
                }
            }
            var cardInfo = await _memberCardService.GetBindCardAsync<ICasaMielSession>(request.Mobile).ConfigureAwait(false);
            if (cardInfo == null) {
                var myda = new Enyim.Caching.Memcached.CasResult<object>();
                if (_memcachedClient.TryGetWithCas(_cachekey, out myda)) {
                    total = (int)myda.Result - 1;
                    _memcachedClient.Cas(Enyim.Caching.Memcached.StoreMode.Replace, _cachekey, total);
                }
                return new BaseResult<string>("", -37, "没有会员卡");
            }
            var trynum = 0;                                                                                 //  trynum += _memcachedClient.GetWithCas<int>(_memcachedPrex + "Icselfregist" + mobile).Result;
            var da = new Enyim.Caching.Memcached.CasResult<object>();
            var _mcouponcachekey = _memcachedPrex + string.Format(CultureInfo.CurrentCulture, Constant.ACTIVITYTMOBILE, request.ActivityId, request.Mobile);
            if (_memcachedClient.TryGetWithCas(_mcouponcachekey, out da)) {
                trynum = (int)da.Result + 1;
                _memcachedClient.Cas(Enyim.Caching.Memcached.StoreMode.Replace, _mcouponcachekey, trynum);
            } else {
                trynum += 1;
                var resultss = _memcachedClient.Cas(Enyim.Caching.Memcached.StoreMode.Add, _mcouponcachekey, trynum);
            }
            var mycouponcount = await _memberCouponRecordService.GetCountAsync<ICasaMielSession>(request.ActivityId, request.Mobile, activityinfo.Flag).ConfigureAwait(false);
            if (trynum > 1) {
                if (activityinfo.Total > 0) {
                    var myda = new Enyim.Caching.Memcached.CasResult<object>();
                    if (_memcachedClient.TryGetWithCas(_cachekey, out myda)) {
                        total = (int)myda.Result - 1;
                        _memcachedClient.Cas(Enyim.Caching.Memcached.StoreMode.Replace, _cachekey, total);
                    }
                }
                _memcachedClient.Remove(_mcouponcachekey);

                return new BaseResult<string>("", 0, "");
            }
            if (mycouponcount >= activityinfo.GetCount) {
                //if (activityinfo.Total > 0) {
                //    var myda = new Enyim.Caching.Memcached.CasResult<object>();
                //    if (_memcachedClient.TryGetWithCas(_cachekey, out myda)) {
                //        total = (int)myda.Result - 1;
                //        _memcachedClient.Cas(Enyim.Caching.Memcached.StoreMode.Replace, _cachekey, total);
                //    }
                //}
                //_memcachedClient.Remove(_cachekey);
                //_memcachedClient.Remove(_mcouponcachekey);
                return new BaseResult<string>("", -33, "您已经领取优惠券");
            }
            var coupon = new MemberCouponRecord { CardNO = cardInfo.CardNO, Mobile = request.Mobile, ActivityId = request.ActivityId, Status = 1, CreateTime = DateTime.Now };
            var req = new AddTicketsReq { Cardno = cardInfo.CardNO, Phoneno = request.Mobile };
            req.Largesstickets = new List<Domain.Request.IC.Ticket>();
            foreach (var item in activityinfo.Tickets) {
                req.Largesstickets.Add(new Domain.Request.IC.Ticket { Ticketid = item.TicketId, Ticketnum = item.Count, Ticketprice = item.Price });
            }

            var d = await _icApiService.Icticketlargess(req).ConfigureAwait(false);
            if (d.code == 0) {
                var jjobj = JsonConvert.DeserializeObject<JObject>(d.content);
                coupon.Largessno = jjobj["largessno"].ToString();
                await _memberCouponRecordService.AddAsync<ICasaMielSession>(coupon).ConfigureAwait(false);
            } else {
                if (activityinfo.Total > 0) {
                    var myda = new Enyim.Caching.Memcached.CasResult<object>();
                    if (_memcachedClient.TryGetWithCas(_cachekey, out myda)) {
                        total = (int)myda.Result - 1;
                        _memcachedClient.Cas(Enyim.Caching.Memcached.StoreMode.Replace, _cachekey, total);
                    }
                }
                coupon.Largessno = d.code.ToString(CultureInfo.CurrentCulture);
                coupon.RequestInfo = JsonConvert.SerializeObject(req);
                //await _memberCouponRecordService.AddAsync<ICasaMielSession>(coupon);
            }
            _memcachedClient.Remove(_mcouponcachekey);
            // return new BaseResult<string>("", 0, "");
            return new BaseResult<string>(d.content, d.code, d.msg);
        }

    }
}
